Audio Engine
🔊 Audio Engine
Digital audio synthesis, effects processing, and analysis — built on the Numerics FFT and Physics Waves foundations.
Namespace: CSharpNumerics.Engines.Audio
🎞️ AudioBuffer
Core audio container with sample data, sample rate, and channel info.
// Create a 1-second mono buffer at 44.1 kHz
var buf = new AudioBuffer(44100, 1, 1.0);
// Wrap existing data
var stereo = new AudioBuffer(new double[] { 0.5, -0.3, 0.8, 0.2 }, 44100, 2);
// Access / properties
double sample = stereo[0, 1]; // frame 0, right channel
int frames = stereo.FrameCount; // 2
double dur = stereo.Duration; // ~0.0000453 s
// Operations
var mono = stereo.ToMono(); // average channels
buf.MixIn(otherBuffer, gain: 0.5); // additive mix
buf.Normalize(); // peak → 1.0
🎛️ SignalGenerator
Generate standard waveforms: Sine, Square, Sawtooth, Triangle, WhiteNoise.
var sine = SignalGenerator.Generate(SignalGenerator.Waveform.Sine, 440, 1.0, 2.0);
var square = SignalGenerator.Generate(SignalGenerator.Waveform.Square, 220, 0.8, 1.0, sampleRate: 48000);
var noise = SignalGenerator.Generate(SignalGenerator.Waveform.WhiteNoise, 0, 0.5, 0.5);
🎹 AudioOscillator
Stateful oscillator with continuous phase — click-free, suitable for real-time synthesis.
var osc = new AudioOscillator(SignalGenerator.Waveform.Sine, 440, 0.8);
// Sample-by-sample
double s = osc.NextSample(44100);
// Batch generate
var buf = osc.GenerateBuffer(duration: 1.0, sampleRate: 44100);
// Modulation: change frequency on the fly
osc.Frequency = 880;
📈 Envelope (ADSR)
Attack-Decay-Sustain-Release amplitude shaping.
var env = new Envelope(attack: 0.05, decay: 0.1, sustain: 0.7, release: 0.3);
double amp = env.Evaluate(t: 0.02); // during attack
double ampR = env.Evaluate(t: 0.8, noteOffTime: 0.5); // during release
// Apply to a buffer (note released at 0.5 s)
env.Apply(buffer, noteOffTime: 0.5);
🎶 Synthesizer
Additive synthesis: combine multiple oscillators + ADSR envelope → AudioBuffer.
var synth = new Synthesizer { SampleRate = 44100 };
synth.AddVoice(new AudioOscillator(SignalGenerator.Waveform.Sine, 440, 1.0));
synth.AddVoice(new AudioOscillator(SignalGenerator.Waveform.Sine, 880, 0.5), gain: 0.3);
synth.Envelope = new Envelope(0.01, 0.05, 0.8, 0.2);
var buf = synth.Render(duration: 1.0, noteOffTime: 0.8);
🔉 AudioFilter
Frequency-domain filtering via FFT → mask → IFFT.
var lp = AudioFilter.Apply(buffer, AudioFilter.FilterType.LowPass, cutoffLow: 1000);
var hp = AudioFilter.Apply(buffer, AudioFilter.FilterType.HighPass, 0, cutoffHigh: 500);
var bp = AudioFilter.Apply(buffer, AudioFilter.FilterType.BandPass, cutoffLow: 200, cutoffHigh: 4000);
🏛️ Reverb
Schroeder-model reverb: parallel comb filters + series all-pass filters.
var reverb = new Reverb(roomSize: 0.7, damping: 0.4, wetMix: 0.3);
var wet = reverb.Process(buffer);
🔁 Delay
Circular-buffer delay with feedback.
var delay = new Delay(delayTime: 0.25, feedback: 0.6, wetMix: 0.4);
var echoed = delay.Process(buffer);
🗜️ Compressor
Dynamic range compression with attack/release envelope.
var comp = new Compressor(threshold: 0.5, ratio: 4.0, attack: 0.01, release: 0.1);
var compressed = comp.Process(buffer);
🎧 SpatialAudio
Stereo panning and distance attenuation.
// Constant-power panning (-1 left, 0 center, +1 right)
var stereo = SpatialAudio.Pan(monoBuffer, pan: -0.3);
// Inverse-distance attenuation
var attenuated = SpatialAudio.AttenuateByDistance(buffer, distance: 5.0);
// Combined: position-based spatialization
var spatial = SpatialAudio.Spatialize(monoBuffer,
sourceX: 10, sourceY: 5, listenerX: 0, listenerY: 0);
📊 SpectrumAnalyzer
Windowed FFT analysis with Hann, Hamming, Blackman, or rectangular windows.
var analyzer = new SpectrumAnalyzer(fftSize: 2048, window: SpectrumAnalyzer.WindowType.Hann);
// Single frame → (frequency, magnitude) pairs
var spectrum = analyzer.Analyze(samples, sampleRate: 44100);
// Averaged over whole buffer (50% overlap)
var avgSpectrum = analyzer.AnalyzeBuffer(buffer);
🎯 PitchDetector
Fundamental frequency detection via autocorrelation or Harmonic Product Spectrum.
var detector = new PitchDetector(fftSize: 4096);
double f0 = detector.Detect(buffer, PitchDetector.Method.Autocorrelation);
// HPS — best with harmonic-rich signals
double f0hps = detector.Detect(buffer, PitchDetector.Method.HarmonicProductSpectrum);
🥁 BeatDetector
Onset detection via spectral flux, with tempo estimation.
var beat = new BeatDetector(frameSize: 1024) { Threshold = 1.5 };
List<double> onsets = beat.Detect(buffer); // onset times in seconds
double bpm = beat.EstimateTempo(buffer); // estimated BPM